package com.example.demo.security.service;

import com.example.demo.config.SecurityProperties;
import com.example.demo.security.vo.JwtUser;
import com.example.demo.security.vo.OnlineUser;
import com.example.demo.utils.EncryptUtils;
import com.example.demo.utils.RedisUtils;
import com.example.demo.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 在线用户信息操作
 * @author zjj
 * @date 2021-05-24
 */
@Slf4j
@Service
public class OnlineUserService {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SecurityProperties properties;

    /**
     * 将在线用户信息保存到redis中
     * @param jwtUser 用户信息
     * @param token token值
     * @param request 请求
     */
    public void save(JwtUser jwtUser, String token, HttpServletRequest request){
        String dept = jwtUser.getDept();
        String ip = StringUtils.getIp(request);
        String browser = StringUtils.getBrowser(request);
        String address = StringUtils.getCityInfo(ip);
        OnlineUser onlineUser = null;
        try {
            onlineUser = new OnlineUser(jwtUser.getUsername(),dept,ip,browser,address, EncryptUtils.desEncrypt(token),new Date());
        }catch (Exception e){
            e.printStackTrace();
        }
        redisUtils.set(properties.getOnlineKey()+token,onlineUser,properties.getTokenValidityInSeconds()/1000);
    }

    /**
     * 监测用户是否在之前已经登陆过，已经登录的话踢下线
     * @param userName 用户名
     * @param igoreToken token值
     */
    public void checkLoginOnUser(String userName,String igoreToken){
        //查询全部数据
        List<OnlineUser> onlineUsers=getAll(userName);
        if (onlineUsers == null || onlineUsers.isEmpty()){
            return;
        }
        for (OnlineUser onlineUser:onlineUsers) {
            try {
                String token = EncryptUtils.desDecrypt(onlineUser.getKey());
                if(StringUtils.isNotBlank(igoreToken)&&!token.equals(igoreToken)){
                    this.kickOut(token);
                }else if(StringUtils.isBlank(igoreToken)){
                    this.kickOut(token);
                }
            }catch (Exception e){
                log.error("checkUser is error"+e);
            }
        }
    }

    /**
     * 查询全部数据，不分页
     * @param filter
     * @return
     */
    public List<OnlineUser> getAll(String filter){
        List<OnlineUser> onlineUsers = new ArrayList<>();

        List<String> keys=redisUtils.scan(properties.getOnlineKey()+"*");
//        降序
        Collections.reverse(keys);
        for (String key : keys){
            OnlineUser onlineUser=(OnlineUser) redisUtils.get(key);
            if(StringUtils.isNotBlank(filter)){
                if(onlineUser.toString().contains(filter)){
                    onlineUsers.add(onlineUser);
                }
            }else{
                onlineUsers.add(onlineUser);
            }
        }
//        排序
        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
        return onlineUsers;
    }

    /**
     * 查询单个用户
     * @param key
     * @return
     */
    public OnlineUser getOne(String key){
        return (OnlineUser)redisUtils.get(key);
    }

    /**
     * 退出登录
     * @param token
     */
    public void kickOut(String token){
        redisUtils.del(properties.getOnlineKey()+token);
    }
}
